package cool.taomu.toolkit.quartz

import java.lang.reflect.Method
import org.aopalliance.intercept.MethodInterceptor
import org.aopalliance.intercept.MethodInvocation
import org.quartz.CronScheduleBuilder
import org.quartz.JobBuilder
import org.quartz.JobDataMap
import org.quartz.JobDetail
import org.quartz.JobKey
import org.quartz.Scheduler
import org.quartz.SchedulerException
import org.quartz.Trigger
import org.quartz.TriggerBuilder
import org.quartz.impl.StdSchedulerFactory
import org.slf4j.LoggerFactory
import com.google.inject.Inject

class QuartzMethodInterceptor implements MethodInterceptor {
    val static LOG = LoggerFactory.getLogger(QuartzMethodInterceptor);

    @Inject
    Scheduler scheduler;
    
    new(){
    //	this.scheduler = StdSchedulerFactory.getDefaultScheduler();
    //	this.scheduler.start();
    }

    override Object invoke(MethodInvocation invocation) throws Throwable {
        var Object target = invocation.getThis();
        var Method method = invocation.getMethod();
        if (method.isAnnotationPresent(ScheduledJob)) {
            var ScheduledJob annotation = method.getAnnotation(ScheduledJob);
            var String cron = annotation.cron();
            LOG.debug("cron:{}",cron)
            registerQuartzJob(target, method.getName(), cron);
        }

        // 继续执行原方法（可选）
        return invocation.proceed();
    }

    private def void registerQuartzJob(Object target, String methodName, String cron) throws SchedulerException {
        var String jobKey = target.getClass().getName() + "." + methodName;
        if (!scheduler.checkExists(JobKey.jobKey(jobKey))) {
            LOG.info("注册 QuartzJob : {}", jobKey)
            var JobDetail jobDetail = JobBuilder.newJob(QuartzInvokerJob).withIdentity(jobKey).usingJobData(
                new JobDataMap()).build();

            jobDetail.getJobDataMap().put(QuartzInvokerJob.TARGET_OBJECT, target);
            jobDetail.getJobDataMap().put(QuartzInvokerJob.METHOD_NAME, methodName);

            var Trigger trigger = TriggerBuilder.newTrigger().withSchedule(CronScheduleBuilder.cronSchedule(cron)).
                build();

            scheduler.scheduleJob(jobDetail, trigger);
        }
    }
}
